package com.draven.mybatis.mapping;

import com.draven.mybatis.session.DravenConfiguration;
import com.draven.mybatis.session.DravenSqlSession;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class DravenMapperRegistry {
  private final DravenConfiguration config;

  private final Map<Class<?>, DravenMapperProxyFactory<?>> knownMappers = new ConcurrentHashMap<>();

  public DravenMapperRegistry(DravenConfiguration config) {
    this.config = config;
  }

  public <T> T getMapper(Class<T> type, DravenSqlSession sqlSession) {
    final DravenMapperProxyFactory<T> mapperProxyFactory = (DravenMapperProxyFactory<T>) knownMappers.get(type);
    return mapperProxyFactory.newInstance(sqlSession);
  }


  public <T> void addMapper(Class<T> type) {
    if (type.isInterface()) {
      if (hasMapper(type)) {
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      boolean loadCompleted = false;
      knownMappers.put(type, new DravenMapperProxyFactory<>(type));
    }

  }

  public <T> boolean hasMapper(Class<T> type) {
    return knownMappers.containsKey(type);
  }
}

